package pipe;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.*;
import java.text.*;
/* objUpdate.java uses a collection to store objects -- July 31 2012
   and shows how to read and write file objects using serialization
   Concepts swing, events, MVC, exceptions and ArrayList are used. */

public class objUpdate
{
  public static void main(String args[])
  {
	objUpdateModel model = new objUpdateModel();
	objUpdateView view = new objUpdateView("Personnel File");
	objUpdateController controller = new objUpdateController(model,view);
  }
}

class objUpdateView extends JFrame
{
  JLabel nLabel=new JLabel("Name: "); JTextField n=new JTextField(15);
  JLabel dLabel=new JLabel("Date: "); JTextField d=new JTextField(15);
  JButton next=new JButton("Next");JButton add=new JButton("Add Person");
  JPanel aPanel=new JPanel(); JPanel bPanel=new JPanel();
  JPanel cPanel=new JPanel();

  public objUpdateView(String title) // constructor builds GUI
  {
    super("title");
    aPanel.add(nLabel);aPanel.add(n);
    bPanel.add(dLabel);bPanel.add(d);
    cPanel.add(next);cPanel.add(add);
    Container con=this.getContentPane();
    con.setLayout(new FlowLayout());
    con.add(aPanel);con.add(bPanel);con.add(cPanel);
	this.addWindowListener(new WindowHandler());
    setBounds(150,150,250,160);setResizable(false);
    setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
    next.setMnemonic('N');add.setMnemonic('A');
    setVisible(true);
  }
  public void buttonActionListeners(ActionListener al)
  {
    next.setActionCommand("next");next.addActionListener(al);
    add.setActionCommand("add");add.addActionListener(al);
  }
}

class objUpdateModel
{
  final String DB = "data.obj"; // parameterize the file name
  final SimpleDateFormat f = new SimpleDateFormat("mm/dd/yyyy");
  ArrayList <Person> persons=new ArrayList<Person>();
  int index=0; Person p;
  void addRecord(JTextField n,JTextField d)
  {
    String name=null;
    name=JOptionPane.showInputDialog(null,
         "Enter a name (eg. John Russell)","Input Person",
         JOptionPane.QUESTION_MESSAGE);
    if(!(name == null))
    {
      String date=null;
      date=JOptionPane.showInputDialog(null,
        "Enter Date (eg. mm/dd/yyyy)","Input Person",
         JOptionPane.QUESTION_MESSAGE);
      if(!(date == null))
      {
        try
        {
          Date date2=f.parse(date); //convert String to Date
          p=new Person(name,date2);persons.add(p); //put in list
          index=persons.lastIndexOf(p); displayRecord(n,d);
        }
        catch(ParseException ex)
        {
          JOptionPane.showMessageDialog(null,
          "Invalid date format!","Input Error",JOptionPane.ERROR_MESSAGE);
        }
	  }
    }
  }
  void displayRecord(JTextField n,JTextField d)
  {
    p=(Person) persons.get(index); //get from list
    n.setText(p.name);d.setText(f.format(p.date));
  }
  void nextRecord(JTextField n,JTextField d)
  {
    updateRecord(n,d); //even if no change
    //move to the next or first record
    if(persons.size()>0)
    {
      index++;index=(index>=persons.size())?0:index;
      displayRecord(n,d);
    }
  }
  void updateRecord(JTextField n,JTextField d)
  {
    p.name = n.getText();
    try {p.date = f.parse(d.getText());}
    catch (ParseException e)
          {System.out.println("Exception :"+e);}
    persons.set(index,p); //put to arrayList
  }
  void loadFile(JTextField n,JTextField d)
  {
    FileInputStream in=null;ObjectInputStream data=null;
	try
	{
	  in=new FileInputStream(DB);data=new ObjectInputStream(in);
	  p=(Person) data.readObject();
	  while( p != null)
	  {
	    persons.add(p);//store Person object in ArrayList collection
	    p=(Person) data.readObject();//read the next record
	  }
	  data.close();
	}
	catch(Exception ex)
	{
	// IOException will always occur on the last read above
	}
	finally {if(persons.size()>0) displayRecord(n,d);}
  }
  void saveFile()
  {
	FileOutputStream out=null;ObjectOutputStream data=null;
	try
	{
	  out=new FileOutputStream(DB);data=new ObjectOutputStream(out);
	  Iterator <Person> itr=persons.iterator();
	  while (itr.hasNext()) {data.writeObject((Person) itr.next());}
	  data.flush();data.close();
	  }
	catch(Exception ex)
	{
	  JOptionPane.showMessageDialog(null,
	  "Error processing output file"+"\n"+ex.toString(),
	  "Output Error",JOptionPane.ERROR_MESSAGE);
	}
    finally {System.exit(0);}
  }
}

class objUpdateController implements ActionListener
{
  objUpdateModel model; objUpdateView view;
  public objUpdateController(objUpdateModel model,objUpdateView view)
  { // constructor sets listeners
    this.model=model;this.view=view;
    WindowHandler.setModel(model); //let WindowHandler know
    WindowHandler.setView(view);
    view.buttonActionListeners(this);
  }
  public void actionPerformed(ActionEvent ae)
  {
	String action_com=ae.getActionCommand();
    JTextField n2=view.n, d2=view.d;
    char c=action_com.charAt(0);switch(c)
    {
    case 'n':model.nextRecord(n2,d2);break;
    case 'a':model.addRecord(n2,d2);break;
    }
  }
}
//an OUTER class that defines a personalized adapter
class WindowHandler extends WindowAdapter
{
  static objUpdateModel model2; static objUpdateView view2;
  static void setModel(objUpdateModel model){model2=model;}
  static void setView(objUpdateView view){view2=view;}
  public void windowOpened(WindowEvent e)
      {model2.loadFile(view2.n,view2.d);}
  public void windowClosing(WindowEvent e) {model2.saveFile();}
}
//an OUTER class that defines a serialized Person class
class Person implements Serializable
{
  String name;Date date;
  Person(String name,Date date) {this.name=name;this.date=date;}
}
